Be more careful with private event data
authorMatthias Clasen <mclasen@redhat.com>
Thu, 20 Jan 2011 03:52:55 +0000 (22:52 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 20 Jan 2011 03:52:55 +0000 (22:52 -0500)
When copying allocated events, also copy the source device.
When synthesizing double or triple clicks, copy the original
button press event including device information.

https://bugzilla.gnome.org/show_bug.cgi?id=639822

gdk/gdkevents.c

index 1878799fea1748db79d678b6be4b235299a19833..43fc086077bcc7a7d3381ed3b2fbf760deb18ea2 100644 (file)
@@ -503,9 +503,9 @@ gdk_event_copy (const GdkEvent *event)
 {
   GdkEventPrivate *new_private;
   GdkEvent *new_event;
-  
+
   g_return_val_if_fail (event != NULL, NULL);
-  
+
   new_event = gdk_event_new (GDK_NOTHING);
   new_private = (GdkEventPrivate *)new_event;
 
@@ -519,21 +519,22 @@ gdk_event_copy (const GdkEvent *event)
 
       new_private->screen = private->screen;
       new_private->device = private->device;
+      new_private->source_device = private->source_device;
     }
-  
+
   switch (event->any.type)
     {
     case GDK_KEY_PRESS:
     case GDK_KEY_RELEASE:
       new_event->key.string = g_strdup (event->key.string);
       break;
-      
+
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
       if (event->crossing.subwindow != NULL)
-       g_object_ref (event->crossing.subwindow);
+        g_object_ref (event->crossing.subwindow);
       break;
-      
+
     case GDK_DRAG_ENTER:
     case GDK_DRAG_LEAVE:
     case GDK_DRAG_MOTION:
@@ -542,28 +543,28 @@ gdk_event_copy (const GdkEvent *event)
     case GDK_DROP_FINISHED:
       g_object_ref (event->dnd.context);
       break;
-      
+
     case GDK_EXPOSE:
     case GDK_DAMAGE:
       if (event->expose.region)
-       new_event->expose.region = cairo_region_copy (event->expose.region);
+        new_event->expose.region = cairo_region_copy (event->expose.region);
       break;
-      
+
     case GDK_SETTING:
       new_event->setting.name = g_strdup (new_event->setting.name);
       break;
 
     case GDK_BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
-      if (event->button.axes) 
-       new_event->button.axes = g_memdup (event->button.axes,
+      if (event->button.axes)
+        new_event->button.axes = g_memdup (event->button.axes,
                                            sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
       break;
 
     case GDK_MOTION_NOTIFY:
-      if (event->motion.axes) 
-       new_event->motion.axes = g_memdup (event->motion.axes,
-                                          sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
+      if (event->motion.axes)
+        new_event->motion.axes = g_memdup (event->motion.axes,
+                                           sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
       break;
 
     default:
@@ -1129,9 +1130,10 @@ gdk_event_get_device (const GdkEvent *event)
  * @event: a #GdkEvent
  * @device: a #GdkDevice
  *
- * Sets the slave device for @event to @device. The event
- * must have been allocated by GTK+, for instance, by
- * gdk_event_copy().
+ * Sets the slave device for @event to @device.
+ *
+ * The event must have been allocated by GTK+,
+ * for instance by gdk_event_copy().
  *
  * Since: 3.0
  **/
@@ -1153,15 +1155,17 @@ gdk_event_set_source_device (GdkEvent  *event,
  * gdk_event_get_source_device:
  * @event: a #GdkEvent
  *
- * This function returns the hardware (slave) #GdkDevice that has triggered the event,
- * falling back to the virtual (master) device (as in gdk_event_get_device()) if the
- * event wasn't caused by interaction with a hardware device. This may happen for
- * example in synthesized crossing events after a #GdkWindow updates its geometry or
- * a grab is acquired/released.
+ * This function returns the hardware (slave) #GdkDevice that has
+ * triggered the event, falling back to the virtual (master) device
+ * (as in gdk_event_get_device()) if the event wasn't caused by
+ * interaction with a hardware device. This may happen for example
+ * in synthesized crossing events after a #GdkWindow updates its
+ * geometry or a grab is acquired/released.
  *
- * If the event does not contain device field, this function will return %NULL.
+ * If the event does not contain a device field, this function will
+ * return %NULL.
  *
- * Returns: a #GdkDevice, or %NULL.
+ * Returns: a #GdkDevice, or %NULL
  *
  * Since: 3.0
  **/
@@ -1189,6 +1193,7 @@ gdk_event_get_source_device (const GdkEvent *event)
  * @event: a valid #GdkEvent
  *
  * Request more motion notifies if @event is a motion notify hint event.
+ *
  * This function should be used instead of gdk_window_get_pointer() to
  * request further motion notifies, because it also works for extension
  * events where motion notifies are provided for devices other than the
@@ -1196,7 +1201,7 @@ gdk_event_get_source_device (const GdkEvent *event)
  * motion events from a %GDK_MOTION_NOTIFY event usually works like this:
  *
  * |[
- * { 
+ * {
  *   /&ast; motion_event handler &ast;/
  *   x = motion_event->x;
  *   y = motion_event->y;
@@ -1450,19 +1455,15 @@ gdk_get_show_events (void)
 
 static void
 gdk_synthesize_click (GdkDisplay *display,
-                     GdkEvent   *event,
-                     gint        nclicks)
+                      GdkEvent   *event,
+                      gint        nclicks)
 {
-  GdkEvent temp_event;
   GdkEvent *event_copy;
   GList *link;
-  
-  g_return_if_fail (event != NULL);
-  
-  temp_event = *event;
-  temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
 
-  event_copy = gdk_event_copy (&temp_event);
+  event_copy = gdk_event_copy (event);
+  event_copy->type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
+
   link = _gdk_event_queue_append (display, event_copy);
 }
 
@@ -1472,6 +1473,8 @@ _gdk_event_button_generate (GdkDisplay *display,
 {
   GdkMultipleClickInfo *info;
 
+  g_return_if_fail (event->type == GDK_BUTTON_PRESS);
+
   info = g_hash_table_lookup (display->multiple_click_info, event->button.device);
 
   if (G_UNLIKELY (!info))